package com.itheima.comment.service.impl;

import com.itheima.comment.document.Comment;
import com.itheima.comment.document.Reply;
import com.itheima.comment.document.ReplyLike;
import com.itheima.comment.dto.CommentReplyDto;
import com.itheima.comment.dto.CommentReplyLikeDto;
import com.itheima.comment.dto.CommentReplySaveDto;
import com.itheima.comment.service.ReplyService;
import com.itheima.comment.vo.ReplyVo;
import com.itheima.common.constants.SystemConstants;
import com.itheima.common.enums.HttpCodeEnum;
import com.itheima.common.exception.LeadNewsException;
import com.itheima.common.util.RequestContextUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ReplyServiceImpl implements ReplyService {

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 保存回复
     *
     * @param dto
     */
    @Override
    public void saveReply(CommentReplySaveDto dto) {
        //获取当前用户的信息 判断是否是匿名用户 匿名就返回错误
        if (RequestContextUtil.isAnonymous()) {
            throw new LeadNewsException(HttpCodeEnum.NEED_LOGIN);
        }

        Reply reply = new Reply();
        reply.setCommentId(dto.getCommentId());
        reply.setContent(dto.getContent());
        reply.setCreatedTime(LocalDateTime.now());
        reply.setHeadImage(RequestContextUtil.getHeader(SystemConstants.LOGIN_USER_IMAGE));
        reply.setLikes(0);
        reply.setUpdatedTime(LocalDateTime.now());
        reply.setNickName(RequestContextUtil.getHeader(SystemConstants.LOGIN_USER_NAME));
        reply.setUserId(Long.parseLong(RequestContextUtil.getUserId()));
        mongoTemplate.insert(reply);

        //查找该评论，回复数量加1
        Query query = Query.query(Criteria.where("_id").is(dto.getCommentId()));
        Update update = new Update();
        update.inc("replies");
        mongoTemplate.findAndModify(query, update, Comment.class);

    }

    /**
     * 点赞回复
     *
     * @param dto
     */
    @Override
    public void like(CommentReplyLikeDto dto) {
        //判断是否为匿名
        if (RequestContextUtil.isAnonymous()) {
            throw new LeadNewsException(HttpCodeEnum.NEED_LOGIN);
        }

        long loginUserId = Long.parseLong(RequestContextUtil.getUserId());
        Query query = new Query(Criteria.where("userId").is(loginUserId)
                .and("replyId").is(dto.getCommentRepayId()));
        ReplyLike replyLike = mongoTemplate.findOne(query, ReplyLike.class);
        int updateCount = 0;

        //判断点赞类型
        if (dto.getOperation() == 1) {
            //点赞
            if (null != replyLike) {
                throw new LeadNewsException("已经点赞过了！");
            }
            replyLike = new ReplyLike();

            replyLike.setReplyId(dto.getCommentRepayId());
            replyLike.setUserId(loginUserId);
            mongoTemplate.insert(replyLike);

            //点赞数+1
            updateCount = 1;
        } else {
            if (null == replyLike) {
                //如果不存在记录则报错
                throw new LeadNewsException("你还没点赞！");
            }
            //存在则删除点赞记录
            mongoTemplate.remove(query, ReplyLike.class);
            //点赞数-1
            updateCount = -1;
        }
        //更新评论中的赞数量
        Query updateQuery = new Query(Criteria.where("id").is(dto.getCommentRepayId()));
        Update update = new Update();
        update.inc("likes", updateCount);
        mongoTemplate.findAndModify(updateQuery, update, Reply.class);
    }

    /**
     * 查询回复列表
     *
     * @param dto
     * @return
     */
    @Override
    public List<ReplyVo> loadPage(CommentReplyDto dto) {
        //非空判断
        if (dto.getMinDate() == null) {
            dto.setMinDate(new Date());
        }
        List<ReplyVo> voList = new ArrayList<>();
        //构建查询条件
        Query query = new Query(Criteria.where("commentId").is(dto.getCommentId())
                .and("createdTime").lt(dto.getMinDate()));
        //每页查询10条记录
        query.limit(10);
        //设置排序
        query.with(Sort.by(Sort.Order.desc("createdTime")));
        //查询
        List<Reply> replies = mongoTemplate.find(query, Reply.class);
        //转成vo
        if(!CollectionUtils.isEmpty(replies)){
            voList = replies.stream().map(ReplyVo::build).collect(Collectors.toList());
        }

        //判断是否为匿名，匿名直接返回结果
        if(!RequestContextUtil.isAnonymous()){
            if(!CollectionUtils.isEmpty(replies)){
                //取出所有评论的id
                List<String> replyIds = replies.stream().map(Reply::getId).collect(Collectors.toList());
                long loginUserId = Long.parseLong(RequestContextUtil.getUserId());

                Query replyLikeQuery = new Query(Criteria.where("userId").is(loginUserId).and("replyId").in(replyIds));

                //查询所有点赞的评论记录
                List<ReplyLike> replyLikes = mongoTemplate.find(replyLikeQuery, ReplyLike.class);
                //如果有结果则标记点赞
                if(!CollectionUtils.isEmpty(replyLikes)){
                    voList.forEach(replyVo -> {
                        replyLikes.forEach(replyLike -> {
                            if(replyVo.getId().equals(replyLike.getReplyId())){
                                replyVo.setOperation(1);
                            }
                        });
                    });
                }
            }
        }
        return voList;
    }
}
